// WindowMiddle.hpp
// Created by Limou on 24-8-21.
//

#ifndef FRONTEND_WINDOWMIDDLE_HPP
#define FRONTEND_WINDOWMIDDLE_HPP

#include <QWidget>
#include <QGridLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QApplication>
#include "../subassembly/SessionFriendArea/SessionFriendArea.hpp"

namespace chat_system::window {
    // >>> class WindowMiddle begin >>>
    class WindowMiddle : public QWidget {
    Q_OBJECT

    private:
        // 组件
        QLineEdit* userSearchBox_; // 用户搜索框部件
        QPushButton* searchFriendButton_; // 添加好友按钮部件
        subassembly::SessionFriendArea* sessionFriendArea_; // 会话或朋友列表区域部件
        subassembly::SessionFriendArea* searchFriendArea_; // 查询列表区域部件

        // 布局
        QGridLayout* gLayoutOfSelf_;

    public:
        // 构造方法
        explicit WindowMiddle(QWidget* parent = nullptr)
        : QWidget(parent)
        , userSearchBox_(new QLineEdit(this))
        , searchFriendButton_(new QPushButton(this))
        , sessionFriendArea_(new subassembly::SessionFriendArea(this))
        , searchFriendArea_(new subassembly::SessionFriendArea(this))
        , gLayoutOfSelf_(new QGridLayout()) {
            this->setElement();
            this->setElementStaticData();
            this->setElementSize();
            this->setElementStyle();
            this->setElementLayout();
            this->setElementSignalSlot();
            this->setElementShow();
        }

        // 析构方法
        ~WindowMiddle() override = default;

        // 获取会话或朋友列表区域方法
        subassembly::SessionFriendArea* getSessionFriendArea() {
            return sessionFriendArea_;
        }

    protected:
        // 重写打印方法
        void paintEvent(QPaintEvent* event) override { // 必须重写这个方法才能使得 this 支持 qss
            (void) event; // 避免警告
            QStyleOption opt; // 创建可以存储绘制部件时所需的各种信息的对象
            opt.initFrom(this); // 将当前部件的属性初始化到 opt 对象中
            QPainter p(this); // 创建了一个 QPainter 对象 p 并将其与当前部件关联
            style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); // TODO: ? 老实说, 这里没看懂，以后研究叭...
        }

        // 重写离开方法
        void leaveEvent(QEvent *event) override {
            (void) event;
            sessionFriendArea_->show();
            searchFriendArea_->hide();
        }

    signals:
        void loadWindowRight(const QString& chatSessionId);

    private:
        // 设置组件方法
        void setElement() {}

        // 设置组件数据方法
        void setElementStaticData() {
            userSearchBox_->setPlaceholderText("搜索");
            searchFriendButton_->setIcon(QIcon(":/window/window_middle/add_friend_button.png"));
        }

        // 设置组件大小方法
        void setElementSize() {
            this->setFixedWidth(253);
            this->setMinimumHeight(500);
            userSearchBox_->setFixedHeight(30);
            searchFriendButton_->setFixedSize(30, 30);
        }

        // 设置组件风格方法
        void setElementStyle() {
            this->setStyleSheet("QWidget { background-color: rgb(247, 247, 247); border: 1px solid rgb(10, 11, 11); }");
            userSearchBox_->setStyleSheet("QLineEdit { border: none; border-radius: 5px; background-color: rgb(226, 226, 226); color: black; padding-left: 5px }"); // NOTE: "padding-left: 5px" 可以让 "搜索" 二字不要太贴左
            QString style = "QPushButton { border: none; border-radius: 5px; background-color: rgb(226, 226, 226);  }";
            style += " QPushButton:pressed { background-color: rgb(240, 240, 240); }"; // 伪类选择器, 点击时改变颜色
            searchFriendButton_->setStyleSheet(style);
        }

        // 设置组件布局方法
        void setElementLayout() {
            // 初始化本组件的布局管理器
            gLayoutOfSelf_->setContentsMargins(2, 10, 2, 10);
            gLayoutOfSelf_->setHorizontalSpacing(0); // 水平子元素间距全部设置无, 后续使用空白 QWidget 细调
            gLayoutOfSelf_->setVerticalSpacing(9); // 垂直子元素间距全部设置, 避免搜索栏和好友列表过于紧密
            this->setLayout(gLayoutOfSelf_);

            // 设置空白部件
            TODO("那个傻呗教程, 居然写这玩意, 等待重构");
            auto spacer1 = new QWidget(this); // 使用空白 widget 填充布局管理器, 让搜索框和列表间距差异化
            auto spacer2 = new QWidget(this);
            auto spacer3 = new QWidget(this);

            spacer1->setStyleSheet("QWidget { border: none; background-color: transparent; }");
            spacer2->setStyleSheet("QWidget { border: none; background-color: transparent; }");
            spacer3->setStyleSheet("QWidget { border: none; background-color: transparent; }");

            spacer1->setFixedWidth(8);
            spacer2->setFixedWidth(8);
            spacer3->setFixedWidth(8);

            // 设置本组件的布局管理器
            gLayoutOfSelf_->addWidget(spacer1, 0, 0);
            gLayoutOfSelf_->addWidget(userSearchBox_, 0, 1);
            gLayoutOfSelf_->addWidget(spacer2, 0, 2);
            gLayoutOfSelf_->addWidget(searchFriendButton_, 0, 3);
            gLayoutOfSelf_->addWidget(spacer3, 0, 4);
            gLayoutOfSelf_->addWidget(sessionFriendArea_, 1, 0, 1, 4); // NOTE: 后面两个参数是横跨的意思
            gLayoutOfSelf_->addWidget(searchFriendArea_, 1, 0, 1, 4); // NOTE: 后面两个参数是横跨的意思
            TODO("上面横跨的写法很垃圾, 等待重构");
        }

        // 设置信号槽方法
        void setElementSignalSlot() {
            // 当搜索文本框被点击时
            connect(searchFriendButton_, &QPushButton::clicked, this, [this](){
                common::Tools::getInstance()->getLogger()->trace("{0} {1} searchFriendButton_ is clicked~", __FILE__, __LINE__);
                QString searchText = userSearchBox_->text();
                if (!searchText.isEmpty()) {
                    TODO("根据搜索文本, 请求网络获取数据列表, 返回得到的 json 数据");
                    TODO("根据 json 显示新的渲染数据列表, 注意隐藏的列表还是会根据网络进行变动, 这样就避免重复渲染");
                    searchFriendArea_->clearItem();
                    TODO("这里加入了测试数据, 等待删除, 并且 addItem 需要重构一个新的, 添加的子项样式需要修改");
                    auto testUser = model::UserModel::makeUser("limou", "113456777", "真是的", QIcon(""));
                    searchFriendArea_->addItem(common::SessionFriendItemType::SESSION_ITEM_TYPE, testUser.getUserId(),
                                               testUser.getUserAvatarIco(),
                                               testUser.getUserNickName(), testUser.getUserPersonalSignature());
                } else { // searchText.isEmpty()
                    TODO("只添加一个没有查询到的子项");
                }

                sessionFriendArea_->hide();
                searchFriendArea_->show();
            });

            // 当列表区域中发生子项的点击时
            connect(sessionFriendArea_, &subassembly::SessionFriendArea::SessionItemIsClicked, this, [this](const QString& chatSessionId){
                common::Tools::getInstance()->getLogger()->trace("get subassembly::SessionFriendArea::SessionItemIsClicked signal, chatSessionId={0}", chatSessionId.toStdString());
                emit this->loadWindowRight(chatSessionId); // NOTE: 这里的 chatSessionId_ 也有可能是群聊 id
            });
        }

        // 设置组件显示方法
        void setElementShow() {
            sessionFriendArea_->show();
            searchFriendArea_->hide();
        }
    };
    // <<< class WindowMiddle end <<<
} // class chat_system::window end

#endif // FRONTEND_WINDOWMIDDLE_HPP
